package com.coderforum.community.service;

import com.coderforum.community.dto.NotificationDTO;
import com.coderforum.community.dto.PaginationDTO;
import com.coderforum.community.enums.NotificationStatusEnum;
import com.coderforum.community.enums.NotificationTypeEnum;
import com.coderforum.community.exception.CustomizeErrorCode;
import com.coderforum.community.exception.CustomizeException;
import com.coderforum.community.mapper.NotificationMapper;
import com.coderforum.community.mapper.UserMapper;
import com.coderforum.community.model.Notification;
import com.coderforum.community.model.NotificationExample;
import com.coderforum.community.model.User;
import com.coderforum.community.model.UserExample;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


/**
 * 通知服务
 * @Author: xuexuehai
 * @MailBox: xuehai.xue@qq.com
 * @Date: 2021/5/6 9:41 下午
 */
@Service
public class NotificationService {

    @Autowired
    private NotificationMapper notificationMapper;

    public PaginationDTO list(Long userId, Integer page, Integer size) {

        PaginationDTO<NotificationDTO> paginationDTO = new PaginationDTO<>();
        Integer totalPage;
        //查询数据表中的数据总数
        NotificationExample notificationExample = new NotificationExample();
        Integer totalCount = (int) notificationMapper.countByExample(notificationExample);
        notificationExample.createCriteria()
                .andReceiverEqualTo(userId);

        if (totalCount % size == 0) {
            totalPage = totalCount / size;
        } else {
            totalPage = totalCount / size + 1;
        }

        //页码范围逻辑校验
        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }

        paginationDTO.setPagination(totalPage, page);

        //size*(page-1) 计算sql中select语句的limit
        Integer offset = size * (page - 1);

        NotificationExample example = new NotificationExample();
        example.createCriteria()
                .andReceiverEqualTo(userId);
        //按创建时间倒序排列
        example.setOrderByClause("gmt_create desc");

        //使用mybatis generator官方的插件RowBoundsPlugin，写在了generatorConfig.xml中
        List<Notification> notifications = notificationMapper.selectByExampleWithRowbounds(example, new RowBounds(offset, size));

        if(notifications.size() == 0){
            return paginationDTO;
        }

        List<NotificationDTO> notificationDTOList = new ArrayList<>();

        for (Notification notification : notifications) {
            NotificationDTO notificationDTO = new NotificationDTO();
            BeanUtils.copyProperties(notification,notificationDTO);
            notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getType()));
            notificationDTOList.add(notificationDTO);
        }


        paginationDTO.setData(notificationDTOList);
        return paginationDTO;
    }

    public Long unreadCount(Long userId) {
        NotificationExample notificationExample = new NotificationExample();
        notificationExample.createCriteria()
                .andReceiverEqualTo(userId)
                .andStatusEqualTo(NotificationStatusEnum.UNREAD.getStatus());
        return notificationMapper.countByExample(notificationExample);

    }

    public NotificationDTO read(Long id, User user) {
        Notification notification = notificationMapper.selectByPrimaryKey(id);

        if(notification == null){
            throw new CustomizeException(CustomizeErrorCode.NOTIFICATION_NOT_FOUND);
        }
        if(!notification.getReceiver().equals(user.getId())){
            throw new CustomizeException(CustomizeErrorCode.READ_NOTIFICATION_FAIL);
        }

        notification.setStatus(NotificationStatusEnum.READ.getStatus());
        notificationMapper.updateByPrimaryKey(notification);

        NotificationDTO notificationDTO = new NotificationDTO();
        BeanUtils.copyProperties(notification,notificationDTO);
        notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getType()));

        return notificationDTO;
    }
}
